www.gusucode.com > VC++ 换肤窗口源码程序 > VC++ 换肤窗口源码程序\code\SkinWin\SkinButton.cpp
//Download by http://www.NewXing.com // SkinButton.cpp : implementation file // #include "stdafx.h" #include "SkinButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSkinButton IMPLEMENT_DYNAMIC(CSkinButton, CButton) CSkinButton::CSkinButton() { m_res = NULL; m_bMouseIn = m_bDown = FALSE; m_backcolor = ::GetSysColor(COLOR_BTNFACE); m_textcolor = ::GetSysColor(COLOR_BTNTEXT); } CSkinButton::~CSkinButton() { } BEGIN_MESSAGE_MAP(CSkinButton, CButton) //{{AFX_MSG_MAP(CSkinButton) ON_WM_PAINT() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_SETFOCUS() ON_WM_KILLFOCUS() ON_WM_ERASEBKGND() ON_WM_KEYDOWN() ON_WM_KEYUP() ON_WM_ENABLE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSkinButton message handlers CString GetPathName( const char * filename ); CString GetFileName( const char * filename, int ext = 0); char *next_token( char *buf, char *token, char *stopchars ); BOOL CSkinButtonResource::LoadSkin(const char *skinfile) { static const char * ps = "Buttons"; char buf[1000]; CString path = GetPathName( skinfile ); GetPrivateProfileString( ps, "Bitmap", "", buf, 1000, skinfile ); if ( *buf == 0 || !m_bmpButton.LoadBitmap( path + "/" + GetFileName( buf,1 )) ) return FALSE; m_TopHeight = GetPrivateProfileInt( ps, "TopHeight", 0, skinfile ); m_BottomHeight = GetPrivateProfileInt( ps, "BottomHeight", 0, skinfile ); m_LeftWidth = GetPrivateProfileInt( ps, "LeftWidth", 0, skinfile ); m_RightWidth = GetPrivateProfileInt( ps, "RightWidth", 0, skinfile ); m_bTrans = GetPrivateProfileInt( ps, "Trans", 0, skinfile ); m_bInited = TRUE; return TRUE; } BOOL CSkinButtonResource::DrawAImage(CDC *pDC, CRect r, CRect sr) { int w = sr.Width(); int h = sr.Height(); int tw = r.Width(); int th = r.Height(); int x = sr.left; int y = sr.top; m_bmpButton.Draw( pDC, 0, 0, CRect(x, y, x + m_LeftWidth, y + m_TopHeight) ); m_bmpButton.Draw( pDC, tw - m_RightWidth, 0, CRect(x + w-m_RightWidth, y, x + w +m_RightWidth,y+m_TopHeight) ); m_bmpButton.Draw( pDC, 0, th-m_BottomHeight, CRect(x, y+h-m_BottomHeight, x+m_LeftWidth, y+h) ); m_bmpButton.Draw( pDC, tw - m_RightWidth, th-m_BottomHeight, CRect(x+w -m_RightWidth, y+h-m_BottomHeight, x+w, y+h) ); m_bmpButton.StretchDraw( pDC, CRect( m_LeftWidth, 0, tw - m_RightWidth, m_TopHeight ), CRect( x + m_LeftWidth, y, x + w-m_RightWidth, y+m_TopHeight ) ); m_bmpButton.StretchDraw( pDC, CRect( m_LeftWidth, th-m_BottomHeight, tw - m_RightWidth, th ), CRect( x + m_LeftWidth, y+h-m_BottomHeight, x + w-m_RightWidth, y+h ) ); m_bmpButton.StretchDraw( pDC, CRect( 0, m_TopHeight, m_LeftWidth, th - m_BottomHeight ), CRect( x, y+m_TopHeight, x + m_LeftWidth , y+h-m_BottomHeight ) ); m_bmpButton.StretchDraw( pDC, CRect( tw - m_RightWidth, m_TopHeight, tw, th - m_BottomHeight ), CRect( x + w-m_RightWidth, y+m_TopHeight, x+w, y+h-m_BottomHeight ) ); m_bmpButton.StretchDraw( pDC, CRect( m_LeftWidth, m_TopHeight, tw - m_RightWidth, th - m_BottomHeight ), CRect( x + m_LeftWidth, y + m_TopHeight, x + w-m_RightWidth, y+h-m_BottomHeight ) ); return TRUE; } BOOL CSkinButtonResource::DrawImage(CDC *pDC, CRect r, int state) { int w = m_bmpButton.Width(); int h = m_bmpButton.Height(); if ( state == 0 ) { //nomral pDC->Draw3dRect( r, RGB(0,0,255), RGB(0, 0, 255 ) ); //pDC->TextOut( 0, 0, "normal"); DrawAImage( pDC, r, CRect( 0, 0, w/5, h ) ); } else if ( state == 1 ) { //hover pDC->Draw3dRect( r, RGB(0,255,0), RGB(0, 255, 0 ) ); //pDC->TextOut( 0, 0, "hover"); DrawAImage( pDC, r, CRect( 3 * w/5, 0, 4 * w/5, h ) ); } else if ( state == 2 ) { //down pDC->Draw3dRect( r, RGB(255,0,0), RGB(255, 0, 0 ) ); //pDC->TextOut( 0, 0, "down"); DrawAImage(pDC, r, CRect( w/5, 0, 2 * w/5, h ) ); } else if ( state == 3 ) { //normal with focus pDC->Draw3dRect( r, RGB(255,255,0), RGB(255, 255, 0 ) ); //pDC->TextOut( 0, 0, "focus"); DrawAImage( pDC, r, CRect( 3 * w/5, 0, 4 * w/5, h ) ); } else if ( state == 4 ) { pDC->Draw3dRect( r, RGB(255,255,0), RGB(255, 255, 0 ) ); DrawAImage( pDC, r, CRect( 2 * w/5, 0, 3 * w/5, h ) ); } return TRUE; } BOOL CSkinButton::DrawImage(CMyBitmap &bmp) { m_bFocus = GetFocus()->GetSafeHwnd() == m_hWnd; m_bEnable = !(GetWindowLong(m_hWnd,GWL_STYLE) & WS_DISABLED); CBitmap *obmp; CDC memDC; CClientDC dc(0); CRect r; GetClientRect(r); memDC.CreateCompatibleDC(&dc); bmp.CreateCompatibleBitmap(&dc, r.Width(), r.Height() ); obmp = memDC.SelectObject( &bmp ); if ( !m_bEnable ) { m_res->DrawImage( &memDC, r, 4 ); } else if ( m_bMouseIn &&m_bDown ) { m_res->DrawImage( &memDC, r, 2); } else if ( m_bMouseIn ) { m_res->DrawImage( &memDC, r, 1 ); } else if ( m_bFocus ) { m_res->DrawImage( &memDC, r, 3 ); } else { m_res->DrawImage( &memDC, r,0 ); } memDC.SelectObject( obmp ); return TRUE; } void CSkinButton::OnPaint() { if ( !m_res || !m_res->m_bInited ) { Default(); return; } //Note:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // to draw button, cliprgn is needed // CPaintDC dc(this); // device context for painting CRect r; CMyBitmap bmp; GetClientRect(r); DrawImage(bmp); SetWindowRgn(bmp.CreateRgnFromFile(RGB(255,0,255)), TRUE ); HRGN hRgn = CreateRectRgn(0, 0, 0, 0); GetWindowRgn(hRgn); ::SelectClipRgn(dc.GetSafeHdc(), hRgn); bmp.Draw( &dc, r ); dc.SelectClipRgn(NULL); DeleteObject(hRgn); //dc.BitBlt( 0, 0, r.Width(), r.Height(), &memDC, 0, 0, SRCCOPY); DrawText( &dc ); // TODO: Add your message handler code here // Do not call CButton::OnPaint() for painting messages } void CSkinButton::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default HRGN hRgn = CreateRectRgn(0, 0, 0, 0); GetWindowRgn(hRgn); if ( PtInRegion( hRgn, point.x, point.y )) { if ( !m_bMouseIn) { m_bMouseIn = TRUE; //GetRegion(); Invalidate(); UpdateWindow(); SetCapture(); } } else { if ( m_bMouseIn) { m_bMouseIn = FALSE; //GetRegion(); Invalidate(); UpdateWindow(); if ( !m_bDown ) ReleaseCapture(); } } DeleteObject(hRgn); } void CSkinButton::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default //CButton::OnLButtonDown(nFlags, point); m_bDown = TRUE; m_bMouseIn = TRUE; //GetRegion(); Invalidate(); UpdateWindow(); SetFocus(); } void CSkinButton::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default ReleaseCapture(); m_bDown = FALSE; if ( m_bMouseIn ) { m_bMouseIn = FALSE; //GetRegion(); Invalidate(); UpdateWindow(); GetParent()->SendMessage( WM_COMMAND, GetDlgCtrlID(), (LPARAM)m_hWnd ); } else { //GetRegion(); Invalidate(); UpdateWindow(); } } void CSkinButton::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default //CButton::OnLButtonDblClk(nFlags, point); } void CSkinButton::OnSetFocus(CWnd* pOldWnd) { //CButton::OnSetFocus(pOldWnd); // TODO: Add your message handler code here } void CSkinButton::OnKillFocus(CWnd* pNewWnd) { //CButton::OnKillFocus(pNewWnd); // TODO: Add your message handler code here } BOOL CSkinButton::DrawText(CDC *pDC ) { CRect r; CString str; GetClientRect( r ); GetWindowText( str ); CFont *ofont; ofont = pDC->SelectObject( GetParent()->GetFont() ); if ( m_bEnable ) pDC->SetTextColor(m_textcolor); else pDC->SetTextColor(RGB(100,100,100)); pDC->SetBkMode(TRANSPARENT); pDC->DrawText( str, r, DT_CENTER | DT_SINGLELINE | DT_VCENTER ); pDC->SelectObject(ofont); return TRUE; } BOOL CSkinButton::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return TRUE; } void CSkinButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if ( nChar == VK_SPACE ) OnLButtonDown( 0, 0 ); //CButton::OnKeyDown(nChar, nRepCnt, nFlags); } void CSkinButton::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if ( nChar == VK_SPACE ) OnLButtonUp( 0, 0 ); //CButton::OnKeyUp(nChar, nRepCnt, nFlags); } BOOL CSkinButton::GetRegion() { CMyBitmap bmp; /* if ( hRgn ) { dc.SelectClipRgn(NULL); DeleteObject(hRgn); } HRGN hRgn = NULL; if ( m_res->m_bTrans ) { HRGN rgn; rgn = bmp.CreateRgnFromFile(RGB(255,0,255)); //strange, must after ClipRgn //SetWindowPos( NULL, 0, 0, bmp.Width(), bmp.Height(), SWP_NOZORDER | SWP_NOMOVE ); HRGN hRgn = CreateRectRgn(0, 0, 0, 0); SetWindowRgn( rgn, TRUE ); GetWindowRgn(hRgn); ::SelectClipRgn(dc.GetSafeHdc(), hRgn); } */ //DrawImage( bmp ); CRgn rgn; rgn.CreateEllipticRgn( 00, 00, 50, 50 ); SetWindowRgn((HRGN)rgn.Detach(), TRUE ); //SetWindowRgn(bmp.CreateRgnFromFile(RGB(255,0,255)), TRUE ); return TRUE; } BOOL CSkinButton::EnableWindow( BOOL bEnable) { CWnd::EnableWindow( bEnable ); OnPaint(); return TRUE; } void CSkinButton::OnEnable(BOOL bEnable) { // CButton::OnEnable(bEnable); if ( bEnable ) ModifyStyle( WS_DISABLED, 0, 0); else ModifyStyle( 0, WS_DISABLED, 0); // TODO: Add your message handler code here Invalidate(); UpdateWindow(); }